package dhz.storage.configurations;

import dhz.storage.filter.JwtFilter;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.*;

@Configuration
public class ShiroConfig {
    @Bean
    public Authenticator authenticator() {
        ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
        authenticator.setRealms(Collections.singletonList(jwtRealm()));
        authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return authenticator;
    }

    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("JwtRealm") JwtRealm jwtRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        List<Realm> list = new ArrayList<>();
        list.add(jwtRealm);
        securityManager.setRealms(list);
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        securityManager.setAuthenticator(authenticator());
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");

        //设置过滤器类型
        Map<String, Filter> filterMap = new HashMap<>();
        filterMap.put("jwt", new JwtFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        Map<String,String> filterRuleMap = new HashMap<>();
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterRuleMap);

        filterRuleMap.put("/test/login", "anon");
        filterRuleMap.put("/test/logged", "jwt");

        /* 网盘整体控制部分 */
        filterRuleMap.put("/disk/allocate", "jwt");
        filterRuleMap.put("/disk/hasDisk", "jwt");
        filterRuleMap.put("/disk/stat", "jwt");
        filterRuleMap.put("/disk/resize", "jwt");

        /* 上传下载部分 */
        filterRuleMap.put("/interface/upload", "jwt");
        filterRuleMap.put("/interface/uploadStatus", "jwt");

        /* 文件系统部分 */
        filterRuleMap.put("/fs/list", "jwt");
        filterRuleMap.put("/fs/delete", "jwt");
        filterRuleMap.put("/fs/copy", "jwt");
        filterRuleMap.put("/fs/mkdir", "jwt");
        filterRuleMap.put("/fs/move", "jwt");
        filterRuleMap.put("/fs/rename", "jwt");
        filterRuleMap.put("/fs/unzip", "jwt");

        /* 文件分享部分 */
        filterRuleMap.put("/share/generate", "jwt");
        filterRuleMap.put("/share/ls", "jwt");
        filterRuleMap.put("/share/count", "jwt");
        filterRuleMap.put("/share/rm", "jwt");

        return shiroFilterFactoryBean;
    }

    @Bean(name = "JwtRealm")
    public JwtRealm jwtRealm(){
        JwtRealm realm = new JwtRealm();
        realm.setAuthenticationCachingEnabled(false);
        return realm;
    }
}
